import axios, { type AxiosInstance } from 'axios'
import { ElMessage } from 'element-plus'
import { isArray } from 'lodash'

const version = '1.0.0'

interface AxiosRequest extends AxiosInstance {
  version?: string
}

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'

const errorCode: Record<string, string> = {
  401: '认证失败，无法访问系统资源',
  403: '当前操作没有权限',
  404: '访问资源不存在',
  default: '系统未知错误，请反馈给管理员',
}

const request: AxiosRequest = axios.create({
  // 超时
  timeout: 30000,
})
request.version = version

request.interceptors.request.use(
  (config) => {
    const baseApiUrl = ''
    const token = 'me-debug'
    const appkey = 'ad5b4fcc5c2464d6e753f58f209c3722'
    let { url } = config
    if (!url.startsWith('http://') && !url.startsWith('https://')) {
      if (!url.startsWith('/')) {
        url = '/' + url
      }
      config.url = baseApiUrl + url
    }
    config.headers['Token'] = token
    config.headers['AppKey'] = appkey
    return config
  },
  (err) => {
    return Promise.reject(err)
  }
)

request.interceptors.response.use(
  (res) => {
    if (res.config.responseType == 'blob') {
      return Promise.resolve(res.data)
    }
    if (typeof res.data === 'string') {
      return Promise.resolve(res)
    }

    if (isArray(res.data)) {
      return Promise.resolve({
        code: 200,
        data: res.data,
      })
    }

    const state = ['resultBody', 'resultMessage', 'status', 'source'].every((key) =>
      Reflect.has(res.data, key)
    )
    if (!state) {
      console.error('接口返回数据格式错误', `${res.config.url}`)
      // return Promise.resolve(res.data)
    } else {
      res.data.data = res.data.resultBody
      res.data.code = res.data.status
      res.data.msg = res.data.resultMessage
    }
    const { code } = res.data
    // 获取错误信息
    const msg = res.data.msg || errorCode[code] || errorCode['default']
    // 二进制数据则直接返回
    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
      return res.data.resultBody
    }
    if (code !== 200 && code !== 1) {
      if (location.search && location.search.includes('debugger')) {
        ElMessage({ message: msg, type: 'error' })
      }
      return Promise.reject(res.data)
    }
    return Promise.resolve(res.data)
  },
  (error) => {
    let { message } = error
    if (message == 'Cancel Request') {
      // cancel
      return Promise.reject(error)
    } else if (message == 'Network Error') {
      message = '后端接口连接异常'
    } else if (message.includes('Operation canceled')) {
      return Promise.reject(error)
    } else if (message.includes('timeout')) {
      message = '系统接口请求超时'
    } else if (message.includes('Request failed with status code')) {
      message = '系统接口' + message.substr(message.length - 3) + '异常'
    }

    if (location.search && location.search.includes('debugger')) {
      ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
    }
    return Promise.reject(error)
  }
)

export default request
